﻿using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using YunHao;

namespace UnknowWorld.CardGame
{
    /// <summary>
    /// 卡牌模型
    /// </summary>
    public class CardModel : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
    {

        void Start()
        {
            RotateInit();
        }

        void Update()
        {
            DragMoveMonitor();
            MoveMonitor();
            RotateMonitor();
        }

        void OnDestroy()
        {

        }

        #region Move And Drag Card;

        /// <summary>
        /// 是否可拖拽
        /// </summary>
        public bool canDrag;
        /// <summary>
        /// 拖动多远使用卡牌
        /// </summary>
        public float useDistance = 3;
        /// <summary>
        /// 移动速率
        /// </summary>
        public float moveSpeed = 1;
        /// <summary>
        /// 拖动中
        /// </summary>
        private bool _draging;
        /// <summary>
        /// 默认位置
        /// </summary>
        private Vector3 _defaultPoint;

        public void OnPointerDown(PointerEventData eventData)
        {
            _draging = true;
            MaxSort();
            _defaultPoint = transform.position;
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            _draging = false;
            float distance = Vector3.Distance(transform.position, _defaultPoint);
            if (distance >= useDistance)
            {
                UseCard();
            }
            else
            {
                moveToPosition = _defaultPoint;
                ResetSort();
            }
        }

        /// <summary>
        /// 拖拽 监控
        /// </summary>
        void DragMoveMonitor()
        {
            if (canDrag && _draging)
            {
                Vector3 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                position.z = _defaultPoint.z;
                moveToPosition = position;
            }
        }

        /// <summary>
        /// 移动到
        /// </summary>
        public Vector3 moveToPosition;

        /// <summary>
        /// 移动 监控
        /// </summary>
        void MoveMonitor()
        {
            if (transform.position != moveToPosition)
            {
                transform.position = Vector3.Lerp(transform.position, moveToPosition, moveSpeed * Time.deltaTime);
            }
        }

        #endregion

        #region Data

        /// <summary>
        /// 卡牌名
        /// </summary>
        public Text cardNameText;
        /// <summary>
        /// 卡牌类型
        /// </summary>
        public Text cardTypeText;
        /// <summary>
        /// 卡牌描述显示
        /// </summary>
        public Text cardDescriptionText;
        /// <summary>
        /// 卡牌等级
        /// </summary>
        public Text cardLevelText;
        /// <summary>
        /// 卡牌图片显示位置
        /// </summary>
        public SpriteRenderer dataSpriteRenderer;
        /// <summary>
        /// 卡片边框显示位置
        /// </summary>
        public SpriteRenderer frameSpriteRenderer;
        /// <summary>
        /// 类型背景
        /// </summary>
        public FrameSprite[] frameSprites;
        /// <summary>
        /// 卡牌
        /// </summary>
        public Card Card
        {
            get
            {
                return _card;
            }
        }
        /// <summary>
        /// 卡牌数据
        /// </summary>
        private Card _card;

        /// <summary>
        /// 绑定卡片
        /// </summary>
        /// <param name="card"></param>
        public void BindCard(Card card)
        {
            _card = card;
            cardNameText.text = _card.FormatName();
            cardTypeText.text = _card.CardTypeString();
            cardDescriptionText.text = _card.FormatDescription();
            cardLevelText.text = FormatCardLevel(_card);
            ResetCardFrame(card.Type);
            CardPool.Instance.LoadCardPictureSprite(_card, (sprite) =>
            {
                dataSpriteRenderer.sprite = sprite;
            });
        }

        /// <summary>
        /// 重置卡牌边框
        /// </summary>
        /// <param name="type"></param>
        void ResetCardFrame(CardType type)
        {
            foreach (var fs in frameSprites)
            {
                if (fs.type == type)
                {
                    frameSpriteRenderer.sprite = fs.sprite;
                    break;
                }
            }
        }

        /// <summary>
        /// 卡牌等级
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        string FormatCardLevel(Card card)
        {
            if (card.MaxLevel == 0)
                return null;
            StringBuilder level = new StringBuilder();
            for (int i = 1; i <= card.MaxLevel; i++)
            {
                if (i <= card.Level)
                {
                    level.Append("★");
                }
                else
                {
                    level.Append("☆");
                }
            }
            return level.ToString();
        }

        /// <summary>
        /// 边框Sprite
        /// </summary>
        [System.Serializable]
        public class FrameSprite
        {
            public CardType type;
            public Sprite sprite;
        }

        #endregion

        #region Card Sort
        /// <summary>
        /// Sprite排行
        /// </summary>
        public SortingGroup sortingGroup;
        /// <summary>
        /// UI 文字
        /// </summary>
        public Canvas sortingCanvas;

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="sortingOrder"></param>
        public void SortGroup(int sortingOrder)
        {
            _order = sortingOrder;
            sortingGroup.sortingOrder = sortingOrder + 1;
            sortingCanvas.sortingOrder = sortingGroup.sortingOrder + 1;
        }
        /// <summary>
        /// 当前排序
        /// </summary>
        private int _order;

        /// <summary>
        /// 前置
        /// </summary>
        void MaxSort()
        {
            sortingGroup.sortingOrder = 9998;
            sortingCanvas.sortingOrder = sortingGroup.sortingOrder + 1;
        }

        /// <summary>
        /// 归位
        /// </summary>
        void ResetSort()
        {
            sortingGroup.sortingOrder = _order + 1;
            sortingCanvas.sortingOrder = sortingGroup.sortingOrder + 1;
        }
        #endregion

        #region Use Card
        /// <summary>
        /// 卡牌使用时调用
        /// </summary>
        public System.Action<bool, CardModel> OnCardUsed { get; set; }

        /// <summary>
        /// 使用卡牌
        /// </summary>
        void UseCard()
        {
            bool used = CanExpendEnergys();
            if (used)
            {//能量足够
                //能量消耗
                ExpendEnergys();
                //卡牌效果
                UseEffects();
                Common.FadeOut2D(transform, 0.2f, () =>
                {//删除卡牌
                    Destroy(gameObject);
                });
            }
            if (null != OnCardUsed) OnCardUsed(used, this);
        }

        /// <summary>
        /// 是否有足够能量消耗
        /// </summary>
        /// <returns></returns>
        bool CanExpendEnergys()
        {
            bool enoughEnergy = true;
            if (null != _card.Energys)
            {
                foreach (var en in _card.Energys)
                {
                    if (!CanExpendEnergy(en)) enoughEnergy = false;
                }
            }
            return enoughEnergy;
        }

        /// <summary>
        /// 是否有足够能量消耗
        /// </summary>
        /// <param name="energy"></param>
        /// <returns></returns>
        bool CanExpendEnergy(Energy energy)
        {
            bool canExpend = false;
            var cgc = GameObject.FindObjectOfType<CardGameControl>();
            if (cgc)
            {
                if (tag == "Player")
                {
                    canExpend = cgc.Player.EnoughEnergy(energy.EnergyValue(_card.Level), energy.Type);
                }
                else
                {
                    canExpend = cgc.Enemey.EnoughEnergy(energy.EnergyValue(_card.Level), energy.Type);
                }
            }
            return canExpend;
        }

        /// <summary>
        /// 消耗能量
        /// </summary>
        void ExpendEnergys()
        {
            if (null != _card.Energys)
            {
                foreach (var en in _card.Energys)
                {
                    ExpendEnergy(en);
                }
            }
        }

        /// <summary>
        /// 消耗能量
        /// </summary>
        /// <param name="energy"></param>
        void ExpendEnergy(Energy energy)
        {
            var cgc = GameObject.FindObjectOfType<CardGameControl>();
            if (cgc)
            {
                if (tag == "Player")
                {
                    cgc.Player.ExpandEnergy(energy.EnergyValue(_card.Level), energy.Type);
                }
                else
                {
                    cgc.Enemey.ExpandEnergy(energy.EnergyValue(_card.Level), energy.Type);
                }
            }
        }

        /// <summary>
        /// 触发所有特效
        /// </summary>
        void UseEffects()
        {
            if (null != _card.Effects)
            {
                foreach (var et in _card.Effects)
                {
                    CardEffect ce = EffectPool.Instance.EffectByKey(et.Key);
                    if (null != ce)
                    { 
                        ce.Use(tag == "Player", _card.EffectValue(et));
                    }
                }
            }
        }

        #endregion

        #region Card Rotate
        /// <summary>
        /// 面向正面
        /// </summary>
        public bool isFront;
        /// <summary>
        /// 反面
        /// </summary>
        public GameObject back;
        /// <summary>
        /// 正面
        /// </summary>
        public GameObject front;
        /// <summary>
        /// 旋转到...
        /// </summary>
        public Vector3 rotateTo;
        /// <summary>
        /// 旋转速率
        /// </summary>
        public float rotateSpeed = 1;
        /// <summary>
        /// 旋转到一半是调用
        /// </summary>
        private System.Action _onHalfRotate;

        /// <summary>
        ///初始化旋转
        /// </summary>
        void RotateInit()
        {
            if (isFront)
            {
                transform.localEulerAngles = new Vector3(0, 180, 0);
                back.SetActive(false);
                front.SetActive(true);
                RotateFront();
            }
            else
            {
                transform.localEulerAngles = new Vector3(0, 0, 0);
                back.SetActive(true);
                front.SetActive(false);
                RotateBack();
            }
        }

        /// <summary>
        /// 旋转监听
        /// </summary>
        void RotateMonitor()
        {
            if (transform.localEulerAngles != rotateTo)
            {
                transform.localEulerAngles = Vector3.Lerp(transform.localEulerAngles, rotateTo, rotateSpeed * Time.deltaTime);
                int y = Mathf.CeilToInt(transform.localEulerAngles.y);
                if (89 <= y && y <= 91)
                {
                    if (null != _onHalfRotate) _onHalfRotate();
                }
            }
        }

        /// <summary>
        /// 转向反面
        /// </summary>
        public void RotateBack()
        {
            rotateTo = new Vector3(0, 0, 0);
            _onHalfRotate = () =>
            {
                back.SetActive(true);
                front.SetActive(false);
            };
            isFront = false;
        }

        /// <summary>
        /// 转向正面
        /// </summary>
        public void RotateFront()
        {
            rotateTo = new Vector3(0, 180, 0);
            _onHalfRotate = () =>
            {
                back.SetActive(false);
                front.SetActive(true);
            };
            isFront = true;
        }
        #endregion
    }
}